package com.property.manage.service.system;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.property.manage.dao.system.MenuMapper;
import com.property.manage.model.system.Menu;
import com.property.manage.model.system.MenuVo;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 描述
 *
 * @author lwb
 * @since 2020/7/15
 */
@Component
@Slf4j
@AllArgsConstructor
public class MenuService {

    private MenuMapper menuMapper;

    public List<Menu> getMenus(Collection<Integer> menuIds){
        QueryWrapper<Menu> wrapper = new QueryWrapper<>();
        wrapper.in("menu_id", menuIds);
        return menuMapper.selectList(wrapper);
    }

    public List<Menu> getAllMenus(){
        return menuMapper.selectList(new QueryWrapper<>());
    }

    public List<MenuVo> convertToMenuVo(List<Menu> menus){
        if(CollectionUtils.isEmpty(menus)){
            return null;
        }

        MenuVo rootMenu = new MenuVo();
        rootMenu.setMenuId(Menu.ROOT_MENU_ID);
        rootMenu.setType(Menu.TYPE_DIR);

        setChildrenMenu(rootMenu, menus);

        return rootMenu.getChildren();
    }

    public void selfAndAncestors(Set<Integer> allMenuIds, Map<Integer, Menu> menuMap, Integer menuId){
        while(!Menu.ROOT_MENU_ID.equals(menuId)){
            //菜单循环了，退出循环
            if(allMenuIds.contains(menuId)){
                break;
            }

            allMenuIds.add(menuId);
            menuId = menuMap.get(menuId).getParentId();
        }
    }

    private void setChildrenMenu(MenuVo menuVo, List<Menu> menus){
        List<MenuVo> childrenMenus = getChildrenMenu(menus, menuVo);
        if (CollectionUtils.isEmpty(childrenMenus)) {
            return;
        }

        List<MenuVo> sortedChildrenMenus = childrenMenus.stream().sorted(Comparator.comparing(Menu::getWeight)).collect(Collectors.toList());
        menuVo.setChildren(sortedChildrenMenus);
        for (MenuVo children : sortedChildrenMenus){
            setChildrenMenu(children, menus);
        }
    }

    private List<MenuVo> getChildrenMenu(List<Menu> menus, MenuVo menuVo){
        if(!Menu.TYPE_DIR.equals(menuVo.getType())){
            return null;
        }
        return menus.stream().
                filter(menu -> menu.getParentId().equals(menuVo.getMenuId())).
                map(menu -> {
                    MenuVo childrenMenu = new MenuVo();
                    childrenMenu.setMenuId(menu.getMenuId());
                    childrenMenu.setIcon(menu.getIcon());
                    childrenMenu.setPath(menu.getPath());
                    childrenMenu.setTitle(menu.getTitle());
                    childrenMenu.setWeight(menu.getWeight());
                    childrenMenu.setChecked(menu.getChecked());
                    childrenMenu.setType(menu.getType());
                    return childrenMenu;
                }).collect(Collectors.toList());
    }
}
